package com.itheima.health.service.impl;

import com.itheima.health.common.MessageConst;
import com.itheima.health.dao.OrderSettingDao;
import com.itheima.health.entity.Result;
import com.itheima.health.exception.BusinessRuntimeException;
import com.itheima.health.pojo.OrderSetting;
import com.itheima.health.service.OrdersettingService;
import com.itheima.health.vo.OrderSettingVo;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class OrdersettingServiceImpl implements OrdersettingService {

    @Autowired
    private OrderSettingDao ordersettingDao;

    /**
     * 根据月份查询
     *
     * @param year
     * @param month
     */
    @Override
    public Result getOrderSettingByMonth(Integer year, Integer month) {
        //判断参数
        if (month < 1 || month > 12 || year == null) {
            throw new BusinessRuntimeException(MessageConst.GET_ORDERSETTING_FAIL);
        }
        //获取月份第一天和最后一天
        LocalDate firstDayOfMonth = LocalDate.of(year, month, 1);
        LocalDate lastDayOfMonth = LocalDate.of(year, month, 1).plusMonths(1).minusDays(1);
        List<OrderSetting> orderSettingList = ordersettingDao.selectByMonth(firstDayOfMonth, lastDayOfMonth);
        List<OrderSettingVo> orderSettingVoList = new ArrayList<>();
        for (OrderSetting orderSetting : orderSettingList) {
            OrderSettingVo orderSettingVo = new OrderSettingVo();
            BeanUtils.copyProperties(orderSetting, orderSettingVo);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(orderSetting.getOrderDate());
            orderSettingVo.setDate(calendar.get(Calendar.DAY_OF_MONTH));
            orderSettingVoList.add(orderSettingVo);
        }
        return new Result(true, MessageConst.GET_ORDERSETTING_SUCCESS, orderSettingVoList);
    }

    /**
     * 文件上传批量
     *
     * @param file
     * @return
     */
    @Override
    public Result upload(MultipartFile file) throws IOException {
        //判断非空
        if (file.isEmpty()) {
            throw new BusinessRuntimeException(MessageConst.IMPORT_ORDERSETTING_FAIL);
        }
        Workbook workbook = new XSSFWorkbook(file.getInputStream());
        XSSFSheet sheet = (XSSFSheet) workbook.getSheetAt(0);
        //获取Sheet页中的最后一行的行号
        int lastRowNum = sheet.getLastRowNum();
        List<OrderSetting> orderSettingListDb = new ArrayList<>();
        for (int i = 1; i <= lastRowNum; i++) {
            OrderSetting orderSetting = new OrderSetting();
            //获取Sheet页中的行
            XSSFRow titleRow = (XSSFRow) sheet.getRow(i);
            //获取行的第1个单元格
            XSSFCell cell1 = titleRow.getCell(0);
            //获取单元格中的文本内容
            Date cellValue1 = cell1.getDateCellValue();
            //获取行的第2个单元格
            XSSFCell cell2 = titleRow.getCell(1);
            //获取单元格中的文本内容
            int cellValue2 = (int) cell2.getNumericCellValue();
            orderSetting.setOrderDate(cellValue1);
            orderSetting.setNumber(cellValue2);
            orderSettingListDb.add(orderSetting);
        }
        //批量新增预约设置
        orderSettingListDb.stream().forEach(orderSetting -> orderSetting.setReservations(0));
        //获取数据库中预约设置数据查询新增是否存在重复
        //重复的设置进行修改
        List<OrderSetting> orderSettings = ordersettingDao.findAll();
        //日期相同做更新
        List<Date> dateListDb = orderSettingListDb.stream().map(OrderSetting::getOrderDate).collect(Collectors.toList());
        List<Date> dateList = orderSettings.stream().map(OrderSetting::getOrderDate).collect(Collectors.toList());
        //获取相同日期
        List<Date> collect = dateListDb.stream().filter(dateList::contains).collect(Collectors.toList());
        List<OrderSetting> updateOrderSetting = orderSettingListDb.stream().filter(orderSetting -> collect.contains(orderSetting.getOrderDate())).collect(Collectors.toList());
        for (OrderSetting orderSetting : updateOrderSetting) {
            //更新的数据预约人数小于之前预约的人数不做处理
            //只更新预约人数大于已预约人数的数据
            ordersettingDao.update(orderSetting);
        }
        //日期不同做新增
        //获取不同日期
        List<Date> differentDate = new ArrayList<>(dateListDb);
        differentDate.addAll(dateList);
        Set<Date> set = new HashSet<>(dateList);
        differentDate.removeIf(set::contains);
        List<OrderSetting> insertOrderSetting = orderSettingListDb.stream().filter(orderSetting -> differentDate.contains(orderSetting.getOrderDate())).collect(Collectors.toList());
        //新增预约设置
        if (insertOrderSetting.size() > 0) {
            ordersettingDao.insert(insertOrderSetting);
        }
        //关闭资源
        workbook.close();
        return new Result(true, MessageConst.IMPORT_ORDERSETTING_SUCCESS);
    }


    /**
     * 06_预约管理可预约单独设置
     *
     * @param orderSetting
     * @return
     */
    @Override
    public void editNumberByDate(@RequestBody OrderSetting orderSetting) {

        Date orderDate = orderSetting.getOrderDate();
        int count = ordersettingDao.findCountByOrderDate(orderDate);
        if (count > 0) {
            //判断设置预约人数是否大于已预约人数
            int reservations = ordersettingDao.selectReservationsByOrderDate(orderSetting.getOrderDate());
            if (reservations > orderSetting.getNumber()) {
                throw new BusinessRuntimeException(MessageConst.GET_ORDERSETTING_FAIL);
            }
            //当前日期已经进行了预约设置，需要进行修改操作
            ordersettingDao.editNumberByDate(orderSetting);
        } else {
            //没有查到orderDate日期对应数据
            ordersettingDao.add(orderSetting);
        }
    }
}
